using System;
using System.Collections.Generic;
using System.Reflection;
using Castle.Components.DictionaryAdapter;
using Castle.Core;
using Castle.MonoRail.Framework;
using Castle.MonoRail.WindsorExtension;
using Castle.Tools.CodeGenerator.Services;
using KenEgozi.Com.Domain.Aggregates.Common;
using KenEgozi.Com.Domain.Aggregates.Post;
using KenEgozi.Com.Domain.Aggregates.Tag;
using KenEgozi.Com.Domain.Factories;
using KenEgozi.Com.Domain.Interfaces.Factories;
using KenEgozi.Com.Domain.Interfaces.Repositories;
using KenEgozi.Com.Domain.Interfaces.Services;
using KenEgozi.Com.Domain.Repositories;
using KenEgozi.Com.Domain.Services;
using KenEgozi.Com.Weblog.Services;
using Rhino.Commons;

namespace KenEgozi.Com.Weblog.Application
{
	public class IoCContainer : RhinoContainer
	{
		public void Initialize()
		{
			AddFacility("RailsFacility", new RailsFacility());
			AddFacility("RhinoTransactionFacility", new RhinoTransactionFacility());
			IUnitOfWorkFactory unitOfWorkFactory = new ActiveRecordUnitOfWorkFactory(new Assembly[] { typeof(Post).Assembly});
			Kernel.AddComponentInstance("ActiveRecordUnitOfWorkFactory", typeof(IUnitOfWorkFactory), unitOfWorkFactory);

			AddComponentWithLifestyle<IDictionaryAdapterFactory, DictionaryAdapterFactory>(LifestyleType.Singleton);
			AddComponentWithLifestyle<ICodeGeneratorServices, DefaultCodeGeneratorServices>(LifestyleType.Transient);

			#region domain
			AddComponentWithLifestyle<ITagFactory, TagFactory>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IPostFactory, PostFactory>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IPostsRepository, PostsRepository>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<Comment>, ARRepository<Comment>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<Download>, ARRepository<Download>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<Tag>, ARRepository<Tag>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<BlogrollEntry>, ARRepository<BlogrollEntry>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<RedirectionEntry>, ARRepository<RedirectionEntry>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<BadIP>, ARRepository<BadIP>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<BadWord>, ARRepository<BadWord>>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IRepository<Password>, ARRepository<Password>>(LifestyleType.Singleton);

			AddComponentWithLifestyle<IUrlFriendlyStringTransformService, UrlFriendlyStringTransformService>(LifestyleType.Singleton);
			AddComponentWithLifestyle<IBlogProjectionsService, BlogProjectionsService>(LifestyleType.Singleton);
			 
			#endregion

			#region web
			// registering all controllers in current assembly
			List<Type> controllers = (new List<Type>(Assembly.GetExecutingAssembly().GetTypes()))
				.FindAll(delegate(Type type)
			{
				return
					!type.IsAbstract &&
					type.IsSubclassOf(typeof(Controller));
			});
			foreach (Type controllerType in controllers)
				AddComponentWithLifestyle(controllerType.FullName, controllerType, LifestyleType.Transient);
			#endregion
			AddComponentWithLifestyle<ICachedItemsService, CachedItemsService>(LifestyleType.Singleton);
			AddComponentWithLifestyle<ISecurityService, SecurityService>(LifestyleType.Singleton);

		}
	}
}